//////////////////////////////////////////////////////////////////////
//
//	Copyright 2010-2011 Rogo's Team. All Rights Reserved
//
//////////////////////////////////////////////////////////////////////
package com.rogo.mvc.core
{
	import com.rogo.mvc.interfaces.IMediator;
	import com.rogo.mvc.interfaces.INotification;
	import com.rogo.mvc.interfaces.IObserver;
	import com.rogo.mvc.interfaces.IView;
	import com.rogo.mvc.sub.observer.Observer;
	
	import flash.utils.Dictionary;
	
	/**
	 * 视图类， 单例
	 * 
	 * <p>负责界面代理的处理， 通知注册 派发...</p>
	 * 
	 * @author coco
	 */	
	public class View implements IView
	{
		public function View()
		{
			super();
			init();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		private static var instance:IView;
		private var observerMap:Dictionary;
		private var mediatorMap:Dictionary;
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		public static function getInstance():IView
		{
			if (!instance) instance = new View();
			return instance;
		}
		
		private function init():void
		{
			observerMap = new Dictionary();
			mediatorMap = new Dictionary();
		}
		
		//--------------------------------------------------------------------------
		//
		//  观察者模式 
		//
		//--------------------------------------------------------------------------
		
		/**
		 * 添加观察者
		 *  
		 * @param notificationName   通知名称
		 * @param observer			 观察者对象
		 */		
		public function registerObserver(notificationName:String, observer:IObserver):void
		{
			var observers:Array = observerMap[notificationName];
			if (observers)
			{
				observers.push(observer);
			}
			else
			{
				observerMap[notificationName] = [observer];
			}
		}
		
		/**
		 * 删除观察者对象
		 * 
		 * @param notificationName	通知名称
		 * @param notifyContext     上下文
		 */		
		public function removeObserver(notificationName:String, notifyContext:Object):void
		{
			var observers:Array = observerMap[notificationName];
			
			for (var i:int = 0; i < observers.length; i++)
			{
				if (Observer(observers[i]).compareNotifyContext(notifyContext))
				{
					observers.splice(i, 1);
					break;
				}
			}
			
			if (observers.length == 0) delete observerMap[notificationName];
		}
		
		/**
		 * 通知观察者
		 * 
		 * @param notification
		 */		
		public function notifyObservers(notification:INotification):void
		{
			// array reference
			var observersRef:Array = observerMap[notification.name];
			if (observersRef)
			{
				// working array
				var observers:Array = new Array();
				var observer:IObserver;
				for (var i:int = 0; i < observersRef.length; i++)
				{
					observer = observersRef[i] as IObserver;
					observers.push(observer);
				}
				
				for (i = 0; i < observers.length; i++)
				{
					observer = observers[i];
					observer.notify(notification);
				}
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Mediator
		//
		//--------------------------------------------------------------------------
		
		/**
		 * 注册视图代理
		 * 
		 * @param mediator
		 */		
		public function registerMediator(mediator:IMediator):void
		{
			if (mediatorMap[mediator.mediatorName]) return;
			
			mediatorMap[mediator.mediatorName] = mediator;
			
			var interests:Array = mediator.listNotificationInterests();
			
			if (interests.length > 0)
			{
				var observer:Observer = new Observer(mediator.notificationHandler, mediator); 
				for (var i:int = 0; i < interests.length; i++)
				{
					registerObserver(interests[i], observer);
				}
			}
			
			mediator.onRegister();
		}
		
		/**
		 * 移除视图代理
		 * 
		 * @param mediatorName
		 */		
		public function removeMediator(mediatorName:String):void
		{
			var mediator:IMediator = mediatorMap[mediatorName] as IMediator;
			if (mediator)
			{
				var interests:Array = mediator.listNotificationInterests();
				for (var i:int = 0; i < interests.length; i++)
				{
					removeObserver(interests[i], mediator);
				}
				delete mediatorMap[mediatorName];
				mediator.onRemove();
			}
		}
		
		/**
		 * 视图代理是否已经存在
		 * 
		 * @param mediatorName
		 * @return 
		 */		
		public function hasMediator(mediatorName:String):Boolean
		{
			return mediatorMap[mediatorName];
		}
		
	}
}